home *** CD-ROM | disk | FTP | other *** search
- NAME ccsfil
- ; Fle CCSFIL.ASM
- ;CHINESE
- ifdef MSDOS
- include mssfil.dat
- else
- include ccsfil.dat
- endif
-
- code segment public 'code'
- extrn spack:near, cmblnk:near, locate:near, decout:near, comnd:near
- extrn putmod:near, poscur:near, clearl:near, isfile:near
- assume cs:code, ds:datas
-
- ; Position cursor for an error message
-
- ERPOS PROC NEAR
- test flags.remflg,dquiet ; quiet screen?
- jnz erpx ; nz = yes
- push dx ; save any preexisting message pointer
- test flags.remflg,dserial ; serial mode display?
- jnz erpo1 ; nz = yes
- test flags.remflg,dserver ; are we a server
- jnz erp0 ; nz = yes, and display is regular
- cmp flags.xflg,1 ; Packet header seen?
- jne erp0 ; No, do as normal
- erpo1: mov dx,offset crlf
- mov ah,prstr
- int dos
- mcmsg erword ,cerword ; put out word Error
- int dos
- pop dx ; restore old pointer
- ret
- erp0:
- ; mov dx,screrr
- mcscr screrr,cscrerr
-
- call poscur
- pop dx ; restore old pointer
- erpx: ret
- ERPOS ENDP
-
- ; Position cursor for number of retries message
-
- RTPOS PROC NEAR
- test flags.remflg,dquiet ; quiet display mode?
- jnz rtpx ; nz = yes
- test flags.remflg,dserver ; in server mode?
- jnz rtp0 ; nz = yes
- cmp flags.xflg,1 ; Packet header seen?
- jne rtp0 ; No, do as normal
- ret
- rtp0: test flags.remflg,dserial ; serial mode display?
- jnz rtp1 ; nz = yes
- ; mov dx,scrnrt
- mcscr scrnrt,cscrnrt
-
- call poscur
- jmp clearl
- rtp1: mcmsg rtword,crtword ; display word Retry
- mov ah,prstr
- int dos
- rtpx: ret
- RTPOS ENDP
-
- ; Reassure user that we acknowledge his ^X/^Z
-
- INTMSG PROC NEAR
- cmp fmtdsp,0 ; non-formatted screen?
- je int5 ; e = yes
- test flags.remflg,dserver ; server mode?
- jnz int4 ; nz = yes
- cmp flags.xflg,0 ; Writing to screen?
- jne int1 ; Yes. Don't do anything
- int4: test flags.remflg,dquiet ; quiet screen?
- jnz int1 ; yes, supress msg
- test flags.remflg,dserial ; serial mode display?
- jz int2 ; ne = no
- int5: mov dx,offset crlf ; yes. output initial cr/lf
- mov ah,prstr
- int dos
- jmp int3 ; display the message
- int2:
- ; mov dx,scrint
- mcscr scrint,cscrint
-
- call poscur
- call clearl
- int3: mcmsg infms7,cinfms7 ; File interrupted?
- cmp flags.cxzflg,'X' ; Yes.
- je int0
- mcmsg infms8,cinfms8 ; File group interrupted?
- cmp flags.cxzflg,'Z'
- je int0
- cmp flags.cxzflg,'C' ; just a control-C?
- je int1 ; e = yes, suppress msg
- mov dl,flags.cxzflg
- mov infms9+6,dl ; store interrupt code letter
- mcmsg infms9, cinfms9
- int0: mov ah,prstr
- int dos
- int1: ret
- INTMSG ENDP
-
- ; Print error message that a high bit set char was found in the file
-
- BITERR PROC NEAR
- test flags.remflg,dquiet ; remote mode?
- jnz biter1 ; nz = yes, no printing
- push bx
- cmp fmtdsp,0 ; non-formatted display?
- je biter3 ; e = yes
- test flags.remflg,dserial ; serial mode display?
- jz biter2 ; z = no
- mov ah,prstr ; display an initial cr/lf
- mov dx,offset crlf
- int dos
- jmp biter3
- biter2:
- ; mov dx,scrhi
- mcscr scrhi,cscrhi
-
- call poscur
- call clearl
- biter3: mov ah,prstr
- mcmsg hibit,chibit
- int dos
- pop bx
- biter1: ret
- BITERR ENDP
-
- ; Clear out message about interrupted file
-
- CXMSG PROC NEAR
- test flags.remflg,dserver ; server mode?
- jnz cxm1 ; nz = yes
- cmp flags.xflg,0 ; Writing to screen?
- jne cxm0 ; Yes. Don't do anything
- cxm1: test flags.remflg,dquiet+dserial ; quiet or serial display?
- jnz cxm0 ; nz = yes
- ; mov dx,scrint
- mcscr scrint,cscrint
- call poscur
- call clearl
- cxm0: ret
- CXMSG ENDP
-
- ; Clear out the old filename on the screen.
-
- CLRFLN PROC NEAR
- test flags.remflg,dquiet ; quiet display?
- jnz clrflnx ; nz = yes
- test flags.remflg,dserial ; serial display mode?
- jnz clrfln1 ; nz = yes, use just cr/lf
- ; mov dx,scrfln
- mcscr scrfln,cscrfln
-
- call poscur
- call clearl ; Clear to end of line
- ret
- clrfln1:push ax ; for serial display, does cr/lf
- mov ah,prstr
- mov dx,offset crlf
- int dos
- pop ax
- clrflnx:ret
- CLRFLN ENDP
-
- PKTSIZE PROC NEAR ; display packet size
- cmp fmtdsp,0 ; formatted display?
- je pktsiz3 ; e = no, no display
- push ax
- push dx
- mov ax,pack.datlen ; packet size (data part)
- add al,trans.chklen ; plus checksum
- adc ah,0
- add ax,3 ; plus LEN, SEQ, TYPE
- cmp ax,94 ; larger than Regular?
- jbe pktsiz1 ; be = no
- add ax,3 ; add Long Packet len and chksum
- pktsiz1:cmp ax,prepksz ; same as previous packet?
- je pktsiz2 ; e = yes, skip display
- mov prepksz,ax ; remember new value
- push ax
- ; mov dx,scrsz ; position cursor
- mcscr scrsz,cscrsz
- call poscur
- call clearl ; clear to end of line
- pop ax
- call decout ; show packet length
- pktsiz2:pop dx
- pop ax
- pktsiz3:ret
- PKTSIZE ENDP
-
- ; some random screen positioning functions
- kbpos:
- ; mov dx,scrkb ; KBytes transferred
- mcscr scrkb,cscrkb
-
- test flags.remflg,dquiet+dserial ; quiet or serial display mode?
- jnz kbpos1
- jmp setup2 ; z = no
- kbpos1: ret ; else ignore postioning request
- perpos:
- ; mov dx,scrper ; Percent transferred
- mcscr scrper,cscrper
-
- test flags.remflg,dquiet+dserial ; quiet or serial display mode?
- jnz perpos1
- jmp setup2 ; z = no
- perpos1: ret ; else ignore postioning request
- frpos:
- ; mov dx,scrfr ; Say renamed file
- mcscr scrfr,cscrfr
-
- jmp setup2
- stpos:
- ; mov dx,scrst ; Print status of file transfer
- mcscr scrst,cscrst
-
- jmp setup2
- nppos:
- ; mov dx,scrnp ; Number of packets sent
- mcscr scrnp,cscrnp
-
- test flags.remflg,dquiet+dserial ; quiet or serial display mode?
- jz setup1 ; z = no
- ret
- rprpos:
- ; mov dx,scrrpr ; Reprompt position
- mcscr scrrpr,cscrrpr
-
- call setup1 ; position cursor
- mov fmtdsp,0 ; turn off formatted display flag
- ret
- nrtpos:
- ; mov dx,scrnrt ; Number of retries
- mcscr scrnrt,cscrnrt
-
- jmp short setup2
- sppos:
- ; mov dx,scrsp ; Send packet location
- mcscr scrsp,cscrsp
-
- jmp short setup1
- rppos:
- ; mov dx,scrrp ; Receive packet location
- mcscr scrrp,cscrrp
-
- jmp short setup1
- ; common service routines for positioning
- setup1: test flags.remflg,dquiet+dserial; quiet or serial display mode?
- jnz setupa ; nz = yes
- cmp fmtdsp,0 ; non-formatted display?
- je setupa ; e = yes
- jmp poscur
- setup2: test flags.remflg,dquiet+dserial; quiet or serial display mode?
- jnz setupa ; nz = yes
- cmp fmtdsp,0 ; non-formatted display?
- je setupa ; e = yes
- call poscur ; no
- jmp clearl
- setupa: test flags.remflg,dquiet ; quiet mode?
- jnz setupx ; nz = yes, do nothing
- push ax ; display cr/lf and return
- push dx
- mov dx,offset crlf
- mov ah,prstr
- int dos
- pop dx
- pop ax
- setupx: ret
-
- ; Start recording of statistics for this operation. [jrd]
- begtim proc near
- test sflag,80h ; is this a duplicate call?
- jz begtim1 ; z = no
- ret ; else just return
- begtim1:push ax
- push cx
- push dx
- xor ax,ax ; clear statistics counters for this file
- mov fsta.prbyte,ax ; bytes received from serial port
- mov fsta.prbyte+2,ax
- mov fsta.psbyte,ax ; bytes sent out serial port
- mov fsta.psbyte+2,ax
- mov fsta.frbyte,ax ; bytes received for this file
- mov fsta.frbyte+2,ax
- mov fsta.fsbyte,ax ; bytes sent for this file
- mov fsta.fsbyte+2,ax
- mov fsta.prpkt,ax ; packets received for this file
- mov fsta.prpkt+2,ax
- mov fsta.pspkt,ax ; packets sent for this file
- mov fsta.pspkt+2,ax
- mov fsta.nakrcnt,ax ; NAKs received for this file
- mov fsta.nakscnt,ax ; NAKs sent for this file
- mov fsta.xstatus,al ; clear status byte
- mov ah,getdate ; get current date, convert to ascii
- int dos
- mov date+9,'0' ; init day of month
- begtim2:cmp dl,10 ; day of month. Ten or more days?
- jl begtim3 ; l = no
- sub dl,10
- inc date+9 ; add up tens of days
- jmp short begtim2 ; repeat for higher order
- begtim3:add dl,'0' ; ascii bias
- mov date+10,dl ; day units
- mov dl,dh ; months (1-12)
- dec dl ; start at zero to index table
- mov dh,0
- mov di,dx ; months
- shl di,1
- add di,dx ; times three chars/month
- mov al,months[di] ; get text string for month
- mov date+12,al
- mov ax,word ptr months[di+1]
- mov word ptr date+13,ax
- mov ax,cx ; year since 1980
- mov dx,0
- mov di,offset date+16 ; destination
- call lnout ; convert number to asciiz in buffer
- ; start time
- mov ah,gettim ; DOS time of day, convert to ascii
- int dos
- mov fsta.btime,dx ; store ss.s low word of seconds
- mov fsta.btime+2,cx ; store hhmm high word of seconds
- mov date,'0' ; init begin hours field
- begtim4:cmp ch,10 ; ten or more hours?
- jl begtim5 ; l = no
- sub ch,10
- inc date ; add up tens of hours
- jmp short begtim4 ; repeat for twenties
- begtim5:add ch,'0' ; ascii bias
- mov date+1,ch ; store units of hours
- mov date+3,'0' ; minutes field
- begtim6:cmp cl,10 ; ten or more minutes?
- jl begtim7 ; l = no
- sub cl,10
- inc date+3 ; add up tens of minutes
- jmp short begtim6 ; repeat for higher orders
- begtim7:add cl,'0' ; ascii bias
- mov date+4,cl ; store units of minutes
- mov date+6,'0' ; seconds field
- begtim8:cmp dh,10 ; ten or more seconds?
- jl begtim9 ; l = no
- sub dh,10
- inc date+6 ; add up tens of seconds
- jmp short begtim8 ; repeat for higher orders
- begtim9:add dh,'0' ; ascii bias
- mov date+7,dh
- mov sflag,80h ; say begtim has been run
- pop dx
- pop cx
- pop ax
- ret
- begtim endp
-
- ; Take snapshot of statistics counters at end of an operation
- ; Enter with ax = 0 for a receive operation, ax = 1 for a send. [jrd]
- endtim proc near
- test sflag,80h ; called more than once without calling begtim?
- jnz endtim1 ; ne = no, so do statistics snapshot
- ret ; yes, do nothing
- endtim1:and sflag,not (1) ; assume receive operation
- or ax,ax ; send (ax > 0), receive (ax = 0) flag
- jz endtim2 ; z = receive opeation
- or sflag,1 ; say send operation
- endtim2:
- push ax
- push cx
- push dx
- mov ah,gettim ; get DOS time of day
- int dos
- mov fsta.etime,dx ; store ss. s
- mov fsta.etime+2,cx ; hhmm
- cmp cx,fsta.btime+2 ; end time less than start time?
- ja endtim2a ; a = above (no need to test low order word)
- cmp dx,fsta.btime ; be. How about low order word
- jae endtim2a ; ae = no wrap around of time
- add ch,24 ; add one day to hours field
- endtim2a:sub dl,byte ptr fsta.btime ; 0.01 sec difference
- jns endtim2b
- dec dh ; borrow a second
- add dl,100 ; make difference positive
- endtim2b:sub dh,byte ptr fsta.btime+1; seconds difference
- jns endtim2c
- dec cl ; borrow a minute
- add dh,60 ; make difference positive
- endtim2c:mov bh,0
- mov bl,dh ; bx has seconds difference
- sub cl,byte ptr fsta.btime+2 ; minutes
- jns endtim2d
- dec ch ; borrow an hour
- add cl,60
- endtim2d:mov al,cl
- mov ah,0
- mul sixty ; minutes to seconds
- add bx,ax ; seconds to bx
- sub ch,byte ptr fsta.btime+3 ; hours difference
- jns endtim2e
- add ch,24
- endtim2e:mov al,ch
- mov ah,0
- mul sixty ; hours to minutes in ax
- mul sixty ; minutes to seconds in dx,ax
- add ax,bx ; ax = seconds
- adc dx,0 ; dx = high word of seconds
- mov fsta.etime,ax ; store elapsed time, seconds, low wd
- mov fsta.etime+2,dx ; high word
- add ssta.etime,ax ; add to session time, low word
- adc ssta.etime+2,dx ; add to session time, high word
-
- mov ax,fsta.prbyte ; port bytes received for this file
- add ssta.prbyte,ax ; port bytes received for this session
- mov ax,fsta.prbyte+2 ; high word
- adc ssta.prbyte+2,ax
- mov ax,fsta.psbyte ; port bytes sent for this file, low word
- add ssta.psbyte,ax ; port bytes sent for this session, low word
- mov ax,fsta.psbyte+2 ; high word
- adc ssta.psbyte+2,ax
-
- test sflag,1 ; completing a receive operation?
- jnz endtim3 ; nz = no, a send operation
- mov ax,tfilsz+2 ; file bytes received, low word
- mov fsta.frbyte,ax
- add ssta.frbyte,ax ; session received file bytes, low word
- mov ax,tfilsz ; high word
- mov fsta.frbyte+2,ax
- adc ssta.frbyte+2,ax
- jmp short endtim4
-
- endtim3:mov ax,tfilsz+2 ; file bytes sent, low word
- mov fsta.fsbyte,ax ; file bytes sent
- add ssta.fsbyte,ax ; session sent file bytes, low word
- mov ax,tfilsz ; high word
- mov fsta.fsbyte+2,ax
- adc ssta.fsbyte+2,ax
-
- endtim4:mov ax,fsta.prpkt ; packets received for this file
- add ssta.prpkt,ax ; session received packets
- mov ax,fsta.prpkt+2
- adc ssta.prpkt+2,ax
- mov ax,fsta.pspkt ; packets sent for this file
- add ssta.pspkt,ax ; session sent packets
- mov ax,fsta.pspkt+2
- adc ssta.pspkt+2,ax
- mov ax,fsta.nakrcnt ; NAKs received for this file
- add ssta.nakrcnt,ax ; session received NAKs
- mov ax,fsta.nakscnt ; NAKs sent for this file
- add ssta.nakscnt,ax ; session sent NAKs
- ; do transaction logging
- cmp tloghnd,0 ; logging transaction? -1 = not opened
- jg endtim5 ; g = logging
- jmp endtim12 ; skip logging
- endtim5:push di ; kind of transaction
- push bx ; save these registers
- mov bx,tloghnd ; handle for transaction log
- mov dx,offset rcvmsg ; assume receive message
- test sflag,1 ; 1 for send, 0 for receive
- jz endtim6 ; z = receive
- mov dx,offset sndmsg ; send message
- endtim6:call strlen ; length of message to cx
- mov ah,write2
- int dos ; write kind of transfer
- ; File names
- cmp diskio.string,0 ; local filename
- je endtim9 ; e = no filename
- test sflag,1 ; a send operation?
- jnz endtim8 ; nz = yes
- ; Receive
- mov dx,offset fsta.xname ; remote name
- call strlen ; length to cx
- jcxz endtim7 ; no name
- mov ah,write2
- int dos
- mov dx,offset diskio.string ; local name
- call strlen ; length to cx
- mov si,offset fsta.xname ; compare these two names
- mov di,dx
- push ds
- pop es
- repe cmpsb ; compare
- je endtim9 ; e = same, so no 'as' msg
- mcmsg fasmsg,cfasmsg ; give 'as' message
- mov cx,faslen ; length
- mov ah,write2
- int dos
- endtim7:mov dx,offset diskio.string ; local name
- call strlen ; get length
- mov ah,write2 ; write local name
- int dos
- jmp short endtim9
-
- endtim8:mov dx,offset diskio.string ; Send. local name
- call strlen
- mov ah,write2
- int dos
- cmp fsta.xname,0 ; using an alias?
- je endtim9 ; e = no
- ; mov dx,offset fasmsg ; give 'as' message
- mcmsg fasmsg,cfasmsg
-
- mov cx,faslen
- mov ah,write2
- int dos
- mov dx,offset fsta.xname ; get alias
- call strlen
- mov ah,write2
- int dos
- ; status of transfer
- endtim9:mov dx,offset atmsg ; say At
- mov cx,atlen ; length
- mov bx,tloghnd ; handle
- mov ah,write2
- int dos
- mov dx,offset date ; write time and date field
- mov cx,datelen ; length
- mov ah,write2
- int dos
- mcmsg fsucmsg ,cfsucmsg ; assume success message
- cmp fsta.xstatus,0 ; 0 = completed?
- je endtim10 ; e = completed
- mcmsg fbadmsg,cfbadmsg ; failed message
- test fsta.xstatus,80h ; interrupted?
- jz endtim10 ; z = no
- mcmsg fintmsg, cfintmsg ; interrupted message
- endtim10:call strlen ; get length to cx
- mov ah,write2
- int dos
- ; file bytes transferred
- mov ax,tfilsz+2 ; file bytes, low word
- mov dx,tfilsz ; high word
- mov di,offset temprp ; work buffer
- call lnout ; transform to ascii
- mov [di],0a0dh ; append cr/lf
- add di,2 ; count them
- mov dx,offset temprp ; start of work buffer
- mov cx,di ; next free byte
- sub cx,dx ; compute length
- mov ah,write2
- int dos
- pop bx
- pop di
- endtim12:mov tfilsz,0 ; clear file size area
- mov tfilsz+2,0
- mov sflag,0 ; say have done ending once already
- mov fsta.xname,0 ; clear statistics "as" name
- pop dx
- pop cx
- pop ax
- ret
- endtim endp
-
- ; SHOW STATISTICS command. Displays last operation and session statistics
- ; 9 March 1987 [jrd]
- shosta proc near ; show file transfer statistics
- mov ah,cmcfm ; confirm with carriage return
- call comnd
- ret ; not confirmed
- nop
- nop
- call endtim ; update statistics, just in case
- push bx
- push cx
- push dx
- mov bx,offset fsta ; pointer to file (Last op) statistics
- mov cx,2 ; two sets to display
- shosta0:push cx ; save loop counter
- cmp cx,2 ; doing Last operation set?
- ;--Pay attention to the next instructon ' je ... '(eflag), Sept.14,1990[zqf]
- ; mov cx,offset lastmsg ; totals for last transfer
- pushf
- mcmsgc lastmsg,clastmsg
- popf
- je shosta1 ; e = yes
- ;-----------
- mov bx,offset ssta ; point to Session statistics area
- ; mov cx,offset sessmsg ; totals for whole session
- mcmsgc sessmsg,csessmsg
- shosta1:
- mov ax,[bx].etime ; elapsed time of operation
- mov dx,[bx].etime+2
- call shoprt ; show result
- ; mov cx,offset pinmsg ; port bytes received
- mcmsgc pinmsg,cpinmsg
- mov ax,[bx].prbyte
- mov dx,[bx].prbyte+2
- call shoprt ; show result
- ; mov cx,offset poutmsg ; port bytes sent
- mcmsgc poutmsg,cpoutmsg
-
- mov ax,[bx].psbyte
- mov dx,[bx].psbyte+2
- call shoprt ; show result
- ; mov cx,offset finmsg ; file bytes received
- mcmsgc finmsg,cfinmsg
-
- mov ax,[bx].frbyte
- mov dx,[bx].frbyte+2
- call shoprt ; show result
- ; mov cx,offset foutmsg ; file bytes sent
- mcmsgc foutmsg,cfoutmsg
-
- mov ax,[bx].fsbyte
- mov dx,[bx].fsbyte+2
- call shoprt ; show result
- ; mov cx,offset pkimsg ; packets received
- mcmsgc pkimsg,cpkimsg
-
- mov ax,[bx].prpkt
- mov dx,[bx].prpkt+2
- call shoprt ; show result
- ; mov cx,offset pkomsg ; packets sent
- mcmsgc pkomsg,cpkomsg
-
- mov ax,[bx].pspkt
- mov dx,[bx].pspkt+2
- call shoprt ; show result
- ; mov cx,offset nakimsg ; naks received
- mcmsgc nakimsg,cnakimsg
-
- mov ax,[bx].nakrcnt
- xor dx,dx
- call shoprt ; show result
- ; mov cx,offset nakomsg ; naks sent
- mcmsgc nakomsg,cnakomsg
-
- mov ax,[bx].nakscnt
- xor dx,dx
- call shoprt
- ; compute baud rate as 10 * total port bytes / elapsed time
- mov ax,[bx].prbyte ; port bytes received, low
- mov dx,[bx].prbyte+2 ; port bytes received, high
- add ax,[bx].psbyte ; port bytes sent, low
- adc dx,[bx].psbyte+2 ; high. [dx,ax] = total port bytes
-
- mov cx,[bx].etime ; low word of sec in cx
- cmp [bx].etime+2,0 ; is high word of sec zero (e.t. < 65536 sec)?
- jz shosta3 ; z = yes, ready for arithmetic
- push ax ; else scale values, save byte count
- push dx
- mov ax,[bx].etime ; elapsed time for file, low word
- mov dx,[bx].etime+2 ; high word
- shr ax,1 ; divide seconds by two, low word
- ror dx,1 ; get low bit of high word
- and dx,8000 ; pick out just that bit
- or ax,dx ; mask in that bit, new time in ax (dx = 0)
- mov cx,ax ; save elapsed time (double-seconds)
- pop dx ; get byte count again
- pop ax
- shr ax,1 ; divide byte count by two also
- push dx
- ror dx,1 ; rotate low bit to high position
- and dx,8000h ; get low bit of high word
- or ax,dx ; byte count divided by two, low word
- pop dx
- shr dx,1 ; and high word
- shosta3:or cx,cx ; is elapsed time (in cx) zero seconds?
- jnz shosta4 ; nz = no
- inc cx ; set time to one second (no div by 0)
- shosta4:div cx ; bytes div seconds, ax = quo, dx = rem
- push dx ; save remainder of bytes/second
- mul ten ; quotient times ten to dx,ax
- pop dx ; discard overflow, recover remainder
- push ax ; save partial baud rate
- xchg ax,dx ; remainder to ax
- xor dx,dx ; clear extension
- mul ten ; remainder times ten too (keep only overflow)
- pop ax ; recover main partial result
- add ax,dx ; add two partial results
- xor dx,dx ; clear extension ( < 65536 baud )
- ; mov cx,offset baudmsg
- mcmsgc baudmsg,cbaudmsg
-
- call shoprt ; show result
- pop cx ; recover loop counter
- dec cx
- jcxz shostax ; cx = 0 means we are done
- jmp shosta0 ; do next set of statistics (session stuff)
- shostax:
- pop dx
- pop cx
- pop bx
- jmp rskp
- shosta endp
-
- ; Print show statistics line. Enter with CX=offset of initial message,
- ; dx,ax with long value
- shoprt proc near
- push ax
- push dx
- mov dx,cx ; setput initial print
- mov ah,prstr ; display title line (dx is ptr)
- int dos
- pop dx
- pop ax
- push di
- mov di,offset temprp ; work space for output
- call lnout ; show long integer
- pop di
- mov dx,offset temprp
- call prtasz ; print asciiz string
- ret
- shoprt endp
-
- ; LNOUT - Table driven unsigned long integer (32 bit) display
- ; Register dx holds high order word and ax holds low order word of unsigned
- ; long integer to be stored in decimal. Storage area is given by DS:[DI]
- ; DI is incremented for each storage, null terminated
- ; Table TENS holds set of double word values of ten raised to powers 0 to 9
- ; TENSLEN holds the number of these double words
- ; All registers preserved. 8 March 1987 [jrd]
- lnout proc near
- push ax
- push bx
- push cx
- push dx
- push si
- xor si,si ; flag to say start printing (no leading 0's)
- mov cx,tenslen ; number of table entries
- lnout1: push cx ; save loop counter
- mov bx,cx ; index into tens double word table
- dec bx ; index starts at zero
- add bx,bx
- add bx,bx ; bx times four (double words to bytes)
- xor cx,cx ; cx is now a counter of subtractions
-
- lnout2: cmp dx,word ptr tens[bx+2] ; pattern 10**(bx/4), high order part
- jb lnout4 ; b = present number is less than pattern
- ja lnout3 ; a = present number is larger than pattern
- cmp ax,word ptr tens[bx] ; high words match, how about lows
- jb lnout4 ; b = present number is smaller than pattern
- lnout3: sub ax,word ptr tens[bx] ; subtract low order words
- sbb dx,word ptr tens[bx+2] ; subtract high order words, w/borrow
- inc cl ; count number of subtractions
- inc si ; flag to indicate printing needed
- jmp lnout2 ; try again to deduct present test pattern
-
- lnout4: or bx,bx ; doing least significant digit?
- jz lnout5 ; z = yes, always print this one
- or si,si ; should we print?
- jz lnout6 ; z = no, not yet
- lnout5: add cl,'0' ; get number of subtractions
- mov [di],cx ; store it (ch is still zero), asciiz
- inc di
- lnout6: pop cx ; recover loop counter
- loop lnout1
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- lnout endp
-
- ; Initialize buffers and clear line
-
- INIT PROC NEAR
- mov hierr,0 ; clear high-bit-seen flag
- test flags.remflg,dquiet ; quiet display mode?
- jnz init3 ; nz = yes
- test flags.remflg,dserial ; serial mode display?
- jnz init2 ; nz = yes
- call cmblnk
- mcmsg cxzhlp,ccxzhlp
- call putmod ; write mode line
- mov fmtdsp,1 ; say doing formatted display
- test flags.remflg,dserver ; server mode?
- jz init1 ; z = no
- ; mov dx,scrser ; move cursor to top of screen
- mcscr scrser,cscrser
-
- call poscur
- mov ah,prstr
- mcmsg infms1,cinfms1 ; say now in server mode
- int dos
- init1: call locate
- mov ah,prstr ; Put statistics headers on the screen
- mcmsg outlin, coutlin
- int dos
- mov wrpmsg,0 ; haven't printed the messsage yet
- mov prepksz,0 ; set previous packet size to zero
- ret
- init2: mov ah,prstr ; print string
- mcmsg cxzser,ccxzser ; status line as a text string
- int dos
- init3: mov wrpmsg,1 ; suppress display of percentage msg
- mov fmtdsp,0 ; say doing unformatted display
- ret
- INIT ENDP
-
-
- ; Output the chars in a packet
-
- ; Called with AX = size of the data, BX = address of source
-
- FILEIO PROC NEAR
-
- ptchr: mov cx,ax
- mov ax,offset outbuf ; routine to call when buffer gets full
- mov chrcnt,maxpack ; size of buffer Data
- mov bufpnt,offset decbuf ; decoded data placed here pending output
- mov bx,offset data ; source of data
- jmp short decode
-
-
- ; CX = Size of data, BX = Address of data, AX = Routine to call to
- ; dump data
-
- decode: push si
- push di
- push es
- push dx
- push ax
- mov ax,ds
- mov es,ax
- pop ax
- mov si,bx ; Source of data
- mov bx,ax ; Coroutine to call
- mov di,bufpnt ; Destination of data
- mov dh,0 ; assume no quote char
- cmp trans.ebquot,'N' ; no quoting?
- je decod1 ; yes, keep going
- cmp trans.ebquot,'Y' ; or not doing it?
- je decod1 ; yes, keep going
- mov dh,trans.ebquot ; otherwise use quote char
-
- decod1: mov rptct,0 ; Reset repeat count
- cmp cx,0 ; any more chars in source?
- jg decod2 ; g = yes
- jmp decod6 ; Else, we're through
- decod2: cld ; forward direction
- lodsb ; Pick up a char
- dec cx ; count number left
- cmp rptq,0 ; Doing repeat quoting?
- je dcod21 ; Nope, skip this part
- cmp al,rptq ; Did we pick up the repeat quote char?
- jne dcod21 ; No, continue processing it
- lodsb ; Get the size
- dec cx ; Modify buffer count
- sub al,20H ; Was made printable
- mov rptct,al ; Remember how many repetitions
- lodsb ; Get the char to repeat
- dec cx ; Modify buffer count
- dcod21: mov ah,0 ; Assume no 8-bit quote char
- cmp al,dh ; This the 8-bit quot char?
- jne decod3 ; ne = no
- lodsb ; Get the real character
- dec cx ; Decrement # chars in packet
- mov ah,80H ; Turn on 8-bit quot char flag
- decod3: cmp al,trans.squote ; Is it the quote char?
- jne decod4 ; ne = no, proceed
- lodsb ; Get the quoted character
- dec cx ; Decrement # of chars in packet
- or ah,al ; save parity (combine with prefix)
- and ah,80h ; only parity
- and al,7FH ; Turn off the parity bit
- cmp al,trans.squote ; Is it the quote char?
- je decod4 ; If so just go write it out
- cmp al,dh ; This the 8-bit quot char?
- je decod4 ; If so, just go write it out
- cmp al,rptq ; Is is the repeat quote character?
- je decod4 ; If so, just write it out
- cmp al,3fh ; char less than '?' ?
- jl decod4 ; l = yes; leave it intact
- cmp al,5fh ; char greater than '_' ?
- jg decod4 ; g = yes; leave it alone
- add al,40H ; Make it a control char again
- and al,7FH ; Modulo 128
- decod4: or al,ah ; or in parity
- dcod41: stosb ; store the character
- dec rptct ; Repeat counter
- dec chrcnt ; Decrement number of chars in dta
- cmp chrcnt,0 ; space left in output buffer?
- jg dcod42 ; g = yes
- push ax ; Save the char
- push cx ; flush output buffer
- push dx
- push bx
- call bx ; Output it if full
- jmp decod5 ; Error return if disk is full
- nop
- pop bx
- pop dx
- pop cx
- mov di,bufpnt
- pop ax ; recover repeated char
- dcod42: cmp rptct,0 ; Write out char again?
- jg dcod41 ; g = yes
- jmp decod1 ; No, get next char
- decod5: pop bx
- pop dx ; dx is pushed twice (really)
- pop cx
- pop dx
- pop es
- pop di
- pop si
- ret
- decod6: mov bufpnt,di ; store address for next output char
- push cx
- push dx
- push bx
- call bx ; flush output buffer before final ret
- jmp decod5 ; Error return if disk is full
- nop
- pop bx
- pop dx
- pop cx
-
- pop dx
- pop es
- pop di
- pop si
- jmp rskp ; Return successfully if done
-
- ; output the buffer, reset bufpnt and chrcnt
-
- outbuf: mov cx,maxpack ; get full size of buffer
- sub cx,chrcnt ; minus space remaining = # to write
- jnc outbu7
- jmp outbf0 ; c = bad buffer pointers
- outbu7: jnz outbu6
- jmp outb11 ; cx = 0 means nothing to do
- outbu6: cmp flags.xflg,1 ; Writing to screen?
- jne outbu0
- jmp outbf2 ; Yes, handle specially
- outbu0:
- mov cx,maxpack ; get full size of buffer
- sub cx,chrcnt ; minus space remaining = # to write
- jc outbf0 ; c = bad buffer pointers
- jnz outbu1
- jmp outb11 ; cx = 0 means nothing to do
- outbu1: push bx
- mov dx,offset decbuf ; address of buffer
- cmp flags.destflg,1 ; disk destination?
- je outbu5 ; e = yes
- cmp flags.eofcz,0 ; end on Control-Z?
- jne outbu5 ; ne = yes, let DOS do it
- push cx ; else map Control-Z to space
- push di
- push es
- push ds
- pop es ; datas to es
- mov di,dx ; scan buffer es:di, cx chars worth
- mov al,ctlz ; look for Control-Z
- cld
- outbu3: repne scasb
- jne outbu4 ; ne = found no Control-Z's
- mov byte ptr [di-1],' ' ; replace Control-Z with space
- jcxz outbu4 ; z = examined all chars
- jmp short outbu3 ; until examined everything
- outbu4: pop es
- pop di
- pop cx
- outbu5: mov bx,diskio.handle ; file handle
- mov ah,write2 ; DOS 2.0 write
- int dos ; Write the record
- pop bx
- jc outbf0 ; c set means disk writing error
- cmp ax,cx ; did we write all the bytes?
- je outbf1 ; e = yes
- call erpos ; no
- mcmsg erms11,erms11 ; Disk full error
- cmp flags.destflg,1 ; writing to disk?
- je outbu0a ; e = yes
- push bx
- mov bx,offset decbuf
- add bx,ax ; look at break character
- cmp byte ptr [bx],ctlz ; ended on Control-Z?
- pop bx
- je outbf1 ; e = yes, say no error
- mcmsg ermes9,cermes9 ; Printer not ready message
- outbu0a:mov ah,prstr ; Tell about it
- int dos
- jmp abfil ; Fix things up before aborting
-
- outbf0: call erpos
- mov ah,prstr ; Tell about it
- mcmsg erms13,cerms13 ; Disk writing error
- cmp flags.destflg,0 ; writing to printer?
- jne outbf0a ; ne = no
- ; mov dx,offset ermes9 ; Printer not ready message
- mcmsg ermes9,cermes9
-
- outbf0a:int dos
- jmp abfil ; Fix things up before aborting
-
- outbf1: add tfilsz+2,cx ; count received chars
- adc tfilsz,0
- test flags.remflg,dserial ; serial mode display?
- jnz outb11 ; nz = yes, skip kbyte and % displays
- call kbpr ; Print the kilobytes received
- call perpr ; Print the percent
- outb11: mov bufpnt,offset decbuf ; Addr for beginning
- mov chrcnt,maxpack ; size of empty buffer
- jmp rskp
-
- outbf2: ; writing to screen
- mov cx,maxpack ; size of full buffer
- sub cx,chrcnt ; minus # of unused in buffer
- jle outb11 ; none to print, don't try
- add tfilsz+2,cx ; count received chars
- adc tfilsz,0
- mov di,offset decbuf ; Where they are
- call prtscr ; Output buffer to screen
- jmp outb11 ; Reset counter & pointer
-
- ; Tidy up before aborting. Retidied by [jrd]
- ABFIL PROC NEAR
- cmp flags.xflg,1 ; Writing to screen?
- je abfil1 ; Yes don't delete "file"
- mov bx,diskio.handle ; get file handle
- cmp bx,4 ; writing to DOS set of files?
- jbe abfil1 ; be = yes, never close them
- mov ah,close2 ; DOS 2.0 file close
- int dos
- cmp flags.abfflg,1 ; Delete what got across or keep it?
- jne abfil1 ; Nope, keep it
- push dx
- mov dx,offset diskio.string ; the full file name
- mov ah,del2 ; DOS 2.0 file delete
- int dos
- pop dx
- abfil1: mcmsg erms10, cerms10 ; Text of message to send
- call errpack ; Send an error packet
- ret
- ABFIL ENDP
-
- ; General routine for sending an error packet. Register BX should
- ; point to the text of the message being sent in the packet
-
- ERRPACK PROC NEAR
- push di
- mov di,offset data ; Where to put the message
- mov al,0
- errp1: mov ah,[bx]
- cmp ah,'$' ; At end of message?
- je errp2
- inc al ; Remember number of chars in msg
- mov [di],ah
- inc bx
- inc di
- jmp errp1
- errp2: pop di
- mov ah,0
- mov pack.datlen,ax
- mov ah,'E' ; And send an error packet
- call spack
- nop ; Return if succeed or fail
- nop
- nop
- ret
- ERRPACK ENDP
-
- ; Get the chars from the file
-
- gtchr: cmp flags.filflg,0 ; Is there anything in the DMA?
- je gtchr0 ; e = yes, proceed
- mov ah,rptq
- mov origr,ah ; Save repeat prefix here
- mov rptct,1 ; Number of times char is repeated
- mov rptval,0 ; Value of repeated char
- call inbuf
- jmp gtchr1 ; No more chars, go return EOF
- nop ; Make three bytes long
- gtchr0: mov bx,offset inbuf
- jmp encode
- gtchr1: mov ax,0ffffh
- ret
-
- ; encode - writes data portion of kermit packet into filbuf
- ; expects BX to contain the address of a routine to refill the buffer,
- ; chrcnt to be the # of chars in the buffer, trans.maxdat to contain
- ; the maximum size of the data packet, bufpnt to contain a pointer to
- ; the source of the characters
- ; Returns: AX/ the number of characters actually written to the buffer
-
- encode: mov cx,trans.maxdat ; Maximum packet size
- push ds
- pop es ; make es:di point to datas segment
- mov di,offset filbuf ; Where to put the data
- mov si,bufpnt ; pointer into source buffer
- mov dl,trans.rquote ; send quote char
- mov dh,0 ; assume no 8-bit quoting
- cmp trans.ebquot,'N' ; not doing 8-bit quoting
- je encod1
- cmp trans.ebquot,'Y' ; or can but won't?
- je encod1
- mov dh,0ffh ; remember we have to do it
- encod1: cmp cx,0 ; any space left in output buffer?
- jg encod2 ; g = yes
- sub di,offset filbuf
- mov ax,di
- mov bufpnt,si ; update pointer into DMA
- jmp rskp
- encod2: cmp chrcnt,0 ; Any data in buffer?
- jg encod3 ; yes, skip over buffer refill
- call bx ; Get another buffer full
- jmp encod8
- mov si,bufpnt ; update position in DMA
- cmp chrcnt,0 ; no characters returned?
- jne encod3 ; Got some, keep going
- jmp encod8 ; none, assume eof
- encod3: dec chrcnt ; Decrement input count
- cld ; forward direction
- lodsb
- cmp flags.eofcz,0 ; Is a control-z an end of file?
- je encd30 ; No, don't have to look for one
- cmp al,'Z'-40H ; Is this a control-Z?
- jne encd30 ; No, skip eof-processing
- mov flags.eoflag,0FFH ; Yes, set eof flag
- mov flags.filflg,0FFH ; No more input in buffer
- mov chrcnt,0 ; Ditto
- jmp encod8 ; Go set character count and return
- encd30: cmp rptq,0 ; Are we doing repeat prefixing?
- je encd3x ; Nope, skip next part
- cmp chrcnt,0 ; Are we on the last character?
- jle encd31 ; Yes, so there's no next character
- cmp rptct,94 ; Max number that we can put in a byte
- je encd31 ; Then that's it
- mov ah,[si] ; Get the next character
- cmp al,ah ; Is current char == next char?
- jne encd31
- inc rptct ; Number of times char appears
- mov rptval,al ; Remember the character
- jmp encod1 ; Keep checking for more
- encd31: cmp rptct,1 ; Were previous characters repeats?
- je encd3x ; No, so just add this char
- cmp rptct,rptmin ; Are we within bounds for repeat prefixing?
- jge encd32 ; Yes, use repeat prefixing
- mov al,rptct
- mov ah,0
- sub si,ax ; Not enough characters to warrant it
- mov rptval,0 ; Clear out this value
- mov al,rptq
- mov origr,al ; Save original repeat prefix
- mov rptq,0 ; Pretend we're not doing prefixing
- mov al,rptct
- mov ah,0
- add chrcnt,ax ; Adjust input buffer pointer
- jmp encod1 ; Reprocess those characters
- encd32: push ax ; Do repeat prefixing - save data
- mov al,rptq ; Add repeat prefix char
- stosb
- dec cx ; Account for it in buffer size
- mov al,rptct ; Get the repeat count
- add al,20H ; Make it printable
- stosb ; Add to buffer
- dec cx
- pop ax ; Get back the actual character
- mov rptct,1 ; Reset repeat count
- mov rptval,0 ; And this
- encd3x: cmp dh,0 ; are we doing 8-bit quoting?
- je encod4 ; e = no, forget this
- test al,80h ; parity on?
- je encod4 ; no, don't bother with this
- and al,7fh ; turn off parity
- mov ah,trans.ebquot ; get quote char
- mov [di],ah ; put in packet
- inc di
- dec cx ; decrement # of chars left
- encod4: mov ah,al ; save character
- and ah,80h ; only parity
- and al,7fh ; turn off parity in character
- cmp al,' ' ; Compare to a space
- jl encod5 ; If less then its a control char
- cmp al,del ; Is the char a delete?
- je encod5 ; e = yes, go quote it
- cmp al,dl ; Is it the quote char?
- je encod6 ; e = yes, go add it
- cmp dh,0 ; are we doing 8-bit quoting?
- je encd41 ; e = no, don't translate it
- cmp al,trans.ebquot ; Is it the 8-bit quote char?
- je encod6 ; e = yes, just output with quote
- encd41: cmp origr,0 ; Doing repeat prefixing?
- je encod7 ; e = no, don't check for quote char
- cmp al,origr ; Is this the repeat quote character
- je encod6 ; e = yes, then quote it
- jmp short encod7 ; else don't quote it
-
- encod5: xor al,40h ; control char, uncontrollify
- encod6: mov [di],dl ; insert control quote char
- inc di
- dec cx
- encod7: or al,ah ; put parity back
- stosb
- dec cx ; Decrement output buffer counter
- cmp rptct,1 ; One occurence of this char?
- jne encd7x
- mov al,origr
- mov rptq,al ; Restore repeat quote char
- jmp encod1 ; Yes, so loop around for some more
- encd7x: dec rptct ; Add another entry of this char
- jmp encod1 ; With quoting and all
-
- encod8: sub di,offset filbuf
- or di,di ; buffer empty?
- je encod9 ; e = yes
- mov ax,di ; report size encoded
- jmp rskp ; return success
- encod9: mov ax,-1 ; Get a minus one
- ret ; return failure
-
-
- inbuf: cmp flags.eoflag,0 ; Have we reached the end?
- jz inbuf0
- ret ; Return if set
- inbuf0: push si
- push dx
- push bx
- push cx
- mov bx,offset buff ; Set the r/w buffer pointer
- mov bufpnt,bx
- mov bx,diskio.handle ; get file handle
- mov cx,buffsz ; record size
- mov dx,bufpnt ; buffer address
- mov ah,readf2 ; DOS 2.0 read a record
- int dos
- jc inbuf1 ; c = error, ie file not open
- or ax,ax ; any bytes read?
- jne inbuf2 ; ne = yes (the number read)
- inbuf1: mov flags.eoflag,0FFH ; Set End-of-file
- mov flags.filflg,0ffh ; Buffer empty
- mov chrcnt,0 ; zero bytes left in buffer
- pop cx
- pop bx
- pop dx
- pop si
- ret
- inbuf2: add tfilsz+2,ax ; total the # bytes transferred so far
- adc tfilsz,0 ; it's a double word
- mov chrcnt,ax ; Number of chars read from file
- mov flags.filflg,0 ; Buffer not empty
- test flags.remflg,dserial ; serial display mode?
- jnz inbuf3 ; nz = yes, skip kbyte and % display
- push ax
- call kbpr ; Print the kilobytes sent
- call perpr ; Print the percent sent
- pop ax
- inbuf3: pop cx
- pop bx
- pop dx
- pop si
- jmp rskp
-
- nulref: mov chrcnt,0 ; No data to return
- jmp rskp
-
- nulr: ret ; dummy buffer emptier
-
- ; Print the number of Kilobytes transferred
-
- kbpr: test flags.remflg,dquiet ; quiet display mode?
- jnz kbpr1 ; nz = yes, no printing
- push bx
- mov ax,tfilsz+2 ; low order word
- mov bx,tfilsz ; high order word
- add ax,512 ; round up, add half the denominator
- adc bx,0
- mov al,ah ; divide double word by 1024, in steps
- mov ah,bl
- shr ax,1
- shr ax,1
- ror bh,1
- ror bh,1
- and bh,not (3fh)
- or ah,bh ; ax has the result
- pop bx
- cmp ax,oldkbt ; is it the same?
- je kbpr1 ; yes, skip printing
- mov oldkbt,ax ; save new # of kb
- push ax
- call kbpos ; Postion the cursor
- pop ax
- call decout ; Print number of KBytes transferred
- kbpr1: ret
-
-
- ; Print the percent transferred
-
- perpr: test flags.remflg,dquiet ; quiet display mode?
- jz perpr1 ; z = no. allow printing
- ret ; skip printing in remote mode
- perpr1: cmp ofilsz,0 ; high word of original file size > 0 ?
- jne perpr3 ; ne = yes, use big file code
- cmp ofilsz+2,0 ; anything here at all?
- jne perpr2 ; ne = yes, use small file code
- ret ; otherwise, quit now
- perpr2: push dx ; case for files < 64 Kb
- mov ax,ofilsz+2 ; original size (low word)
- mov denom,ax
- mov dx,tfilsz ;transferred size times 256 in [dx,ax]
- mov ax,tfilsz+2
- mov dh,dl ; whole value multiplied by 256
- mov dl,ah
- mov ah,al
- mov al,0
- mov cx,denom ; round up, add half the denominator
- shr cx,1
- add ax,cx
- adc dx,0
- div denom ; (256*xfer)/orig. ax = quo, dx = rem
- mul onehun ; multiply quotient above by 100
- mov al,ah ; divide result (ax) by 256
- mov ah,0 ; percentage is in ax
- jmp perpr4 ; finish in common code
- perpr3: push dx ; case for file size > 64 KB
- mov ax,ofilsz+2 ; original file size low order word
- shr ax,1 ; divide by 2
- mov al,ah ; divide again by 256 for total of 512
- mov ah,0 ; clear ah
- mov dx,ofilsz ; high order word
- xchg dh,dl ; do shl dx,cl=7
- ror dx,1 ; old low bit of dh to high bit of dh
- and dl,80h ; clear lower bits. divided by two
- or ax,dx ; paste together the two parts into ax
- mov denom,ax ; denom = original size divided by 512
- mov dx,tfilsz ; high order word of transferred size
- mov ax,tfilsz+2 ; low order word
- mov cx,denom ; round up, add half the denominator
- shr cx,1
- add ax,cx
- adc dx,0
- div denom ; xfer/(512*orig). ax=quot, dx=rem
- mul onehun ; times 100 for 512*percentage, in ax
- mov al,ah ; divide ax by 512
- mov ah,0
- shr ax,1 ; final percentage, in ax
- perpr4: pop dx
- cmp ax,oldper ; same as it was before?
- je perpr7 ; yes, don't bother printing
- mov oldper,ax ; remember this for next time
- cmp wrpmsg,0 ; did we write the percentage message?
- jne perpr5 ; ne = yes, skip this part
- push ax
- call perpos ; position cursor
- mcmsg permsg,cpermsg
- mov ah,prstr
- int dos ; write out message
- pop ax
- mov wrpmsg,1 ; init flag so we don't do it again
- perpr5: push ax
- call perpos ; Position the cursor
- pop ax
- cmp ax,onehun ; > 100% ?
- jle perpr6 ; no, accept it
- mov ax,onehun ; else just use 100
- perpr6: call decout
- mov dl,25h ; Load a percent sign
- mov ah,conout ; Print the character
- int dos
- perpr7: ret
- ; GETFIL, called only by send code
- getfil: mov flags.filflg,0ffh ; Say nothing is in the buffer
- mov flags.eoflag,0 ; Not the end of file
- mov dx,offset diskio.dta ; data transfer address
- mov ah,setdma ; set disk transfer address
- int dos ; do it
- mov cx,0 ; attributes: find only normal files
- mov dx,offset diskio.string ; filename string (may have wild cards)
- mov ah,first2 ; DOS 2.0 search for first
- int dos ; get file's characteristics
- pushf ; save c flag
- mov ah,setdma ; reset dta address
- mov dx,offset buff ; restore dta
- int dos
- popf ; restore status of search for first
- jnc getfi1 ; nc = ok so far
- ret ; else take error exit
- getfi1:
- mov dx,offset diskio.string ; original file spec (may be wild)
- mov di,offset templp ; place for path part
- mov si,offset templf ; place for filename part
- call fparse ; split them
- mov si,offset diskio.fname ; current filename from DOS
- call strcat ; local path + diskio.fname
- mov si,di ; make it a source
- mov di,offset diskio.string ; new destination
- call strcpy ; new string = old path + DOS's filename
- mov ah,open2 ; DOS 2.0 file open
- mov al,0 ; open readonly
- cmp dosnum,2 ; above DOS 2?
- jna getfi1a ; na = no, so no shared access
- mov al,0+40h ; open readonly, deny none
- getfi1a:mov dx,offset diskio.string ; filename string
- int dos
- jnc getfi2 ; nc = opened the file
- ret ; else take error return
- getfi2: mov diskio.handle,ax ; save file handle
- mov ax,diskio.sizehi ; get file size (high order word)
- mov ofilsz,ax ; new form
- mov ax,diskio.sizelo ; low order word
- mov ofilsz+2,ax ; new form
- mov ax,0
- mov tfilsz,ax ; Set bytes sent to zero
- mov tfilsz+2,ax
- mov ax,-1 ; get a minus one
- mov oldkbt,ax
- mov oldper,ax
- cmp ofilsz,0 ; Null file?
- jne getfl0 ; Nope
- cmp ofilsz+2,0 ; Null file?
- jne getfl0 ; Nope
- mov flags.eoflag,0FFH ; yes. Set EOF
- getfl0: jmp rskp
-
- ; GTNFIL called by send code to get next file. Rewritten by [jrd]
-
- gtnfil: cmp flags.cxzflg,'Z' ; Did we have a ^Z?
- jne gtn1 ; ne = no, else done sending files
- ret ; take failure exit
-
- gtn1: mov flags.filflg,0ffh ; Nothing in the DMA
- mov flags.eoflag,0 ; Not the end of file
- mov dx,offset diskio.dta ; point at dta
- mov ah,setdma ; set the dta address
- int dos
- mov ah,next2 ; DOS 2.0 search for next
- int dos
- pushf ; save carry flag
- mov ah,setdma ; restore dta
- mov dx,offset buff
- int dos
- popf ; recover carry flag
- jc gtn4 ; carry set means no more files found
- call endtim ; get tod of end of file transfer
- mov di,offset templp ; place for path part
- mov si,offset templf ; place for filename part
- mov dx,offset diskio.string ; current full filename
- call fparse ; split them
- mov si,offset diskio.fname ; new filename part from DOS
- call strcat ; rejoin path and new filename
- mov si,di ; new source
- mov di,offset diskio.string ; place for whole new name
- call strcpy ; copy new string
- mov dx,offset diskio.string ; address of new string
- mov ah,open2 ; DOS 2.0 file open
- mov al,0 ; open readonly
- cmp dosnum,2 ; above DOS 2?
- jna gtn3 ; na = no, so no shared access
- mov al,0+40h ; open readonly, deny none
- gtn3: int dos
- jc gtn4 ; c = could not open the file
-
- mov diskio.handle,ax ; save file handle
- call begtim ; start statistics counter
- mov ax,diskio.sizehi ; get file size (high order word)
- mov ofilsz,ax ; save as original file size
- mov ax,diskio.sizelo ; low order word
- mov ofilsz+2,ax
- mov tfilsz,0 ; Set bytes sent to zero
- mov tfilsz+2,0
- mov oldkbt,-1
- mov oldper,-1
- mov ax,1 ; tell statistics this was a send operation
- cmp ofilsz,0 ; Null file?
- jne gtn2 ; Nope
- cmp ofilsz+2,0 ; Null file?
- jne gtn2 ; Nope
- mov flags.eoflag,0FFH ; Set EOF
- gtn2: jmp rskp ; set success condition
- gtn4: ret ; set failure condition
-
-
- ; Get the file name from the data portion of the F packet or from locally
- ; specified override filename (in locfil)
- ; prints the filename, handles any manipulation of the filename
- ; necessary, including changing the name to prevent collisions
- ; Called by READ (receive a file, at rfil32)
-
- gofil: push si
- push di
- mov si,offset data ; filename in packet
- cmp flags.xflg,0 ; receiving to screen
- je gofil0a ; e = no
- mov diskio.handle,1 ; screen is stdout, handle 1
- cmp data,0 ; filename given?
- jne gofil0a ; ne = yes
- mov si,offset toscreen ; then use this dummy name
- gofil0a:mov di,offset diskio.string ; place where prtfn prints name
- call strcpy ; copy pkt filename to diskio.string
- mov di,offset fsta.xname ; statistics filespec save area
- call strcpy ; record external name
- pop di
- pop si
- cmp flags.xflg,0 ; Receiving to screen? (X versus F)
- je gofil1 ; e = no
- jmp gofi20 ; Yes. so skip this stuff
- gofil0: cmp flags.destflg,2 ; file destination = screen?
- jne gofil1 ; ne = no
- jmp gofi20 ; yes
- gofil1: test flags.remflg,dquiet ; quiet display mode?
- jnz gofi1c ; nz = yes, don't display filename
- call prtfn ; display the packet's filename
- gofi1c: mov byte ptr diskio.string,0 ; clear final filename
- cmp flags.destflg,0 ; writing to printer?
- jne gofi1a ; ne = no, go on
- mov ax,offset printer ; this is filename now
- mov diskio.handle,4 ; system printer is handle 4
- jmp gofi16 ; and do it directly
- gofi1a: mov flags.nmoflg,0 ; assume no override name
- cmp byte ptr locfil,0 ; overriding name from other side?
- jne gofi1e ; ne = yes
- jmp gofil4 ; e = No. get the other end's filename
- gofi1e: mov flags.nmoflg,0ffh ; say using an override name
- mov ax,offset locfil ; get local override filename
- cmp word ptr locfil+1,003ah ; colon+null?(primative drive spec A:)
- je gofil3 ; e = yes, skip screwy DOS response (No Path)
- cmp word ptr locfil,'..' ; parent directory?
- jne gofi1g ; ne = noo
- cmp word ptr locfil+1,002eh ; dot dot + null?
- je gofi1b ; e = yes, process as directory
- gofi1g: cmp word ptr locfil,002eh ; dot + null (parent dir)?
- je gofi1b ; e = yes, process as directory
- call isfile ; does it exist?
- jnc gofi1f ; nc = file exists
- test filtst.fstat,80h ; serious error?
- jz gofil3 ; z = no, just no such file
- jmp gofi18a ; else quit here
- gofi1f: test byte ptr filtst.dta+21,10H ; subdirectory name?
- jnz gofi1b ; nz = yes
- cmp byte ptr locfil+2,5ch ; could it be a root directory like b:\?
- jne gofi1d ; ne = no. (DOS is not helpful with roots)
- cmp byte ptr locfil+3,0 ; and is it terminated in a null?
- je gofi1b ; e = yes, so it is a root spec
- gofi1d: test byte ptr filtst.dta+21,0fh ; r/o, hidden, system, vol label?
- jz gofil3 ; z = no
- jmp gofi18a ; yes. Complain and don't transfer file
- gofi1b: mov dx,offset locfil ; locfil is a subdirectory name
- call strlen ; get its length w/o terminator
- jcxz gofil2 ; zero length
- dec cx ; examine last char
- push bx ; save bx
- mov bx,cx
- add bx,dx
- cmp byte ptr [bx],5ch ; ends in backslash?
- je gofil2 ; e = yes
- cmp byte ptr [bx],2fh ; maybe forward slash?
- je gofil2 ; e = yes
- mov byte ptr [bx + 1],5ch ; no slash yet. use backslash
- mov byte ptr [bx + 2],0 ; plant new terminator
- gofil2: pop bx
-
- gofil3: mov di,offset templp ; local path
- mov si,offset templf ; local filename
- mov dx,offset locfil ; local string
- call fparse ; split local string
- mov di,offset temprp ; remote path
- mov si,offset temprf ; remote file
- mov dx,offset data ; remote string
- push bx ; guard against long filenames
- mov bx,offset data
- mov byte ptr [bx+64],0 ; force filename to be <= 64 text chars
- pop bx
- call fparse ; split remote string
- mov si,offset templp ; copy local path to
- mov di,offset data ; final filename
- call strcpy ; do the copy
- gofi3a: mov si,offset templf ; assume using local file name
- cmp byte ptr templf,0 ; local file name given?
- jne gofi3b ; ne = yes
- mov si,offset temprf ; else use remote file name
- gofi3b: call strcat ; do the append
- ; now offset data holds the new filename
- ;
- gofil4: mov ax,offset data ; assume we're writing to disk
- push bx ; guard against long filenames
- mov bx,offset data
- mov byte ptr [bx+64],0 ; force filename to be <= 64 text char
- pop bx
- ; recheck legality of filename in 'data'
- gofil5: mov di,offset temprp ; remote path
- mov si,offset temprf ; remote file
- mov dx,offset data ; remote string
- call strlen ; get original size
- push cx ; remember it
- call fparse ; further massage filename
- push si ; put pieces back together
- call verfil ; verify each char in temprf string
- mov si,di ; get path part first
- mov di,dx ; set destination
- call strcpy ; copy in path part
- pop si ; recover (new) filename
- cmp byte ptr [si],'.' ; does filename part start with a dot?
- jne gofil5a ; ne = no
- push di ; save regs
- push si
- mov di,offset rdbuf ; a work area
- mov byte ptr [di],'X' ; start name with letter X
- inc di
- call strcpy ; copy rest of filename
- mov di,si
- mov si,offset rdbuf ; copy new name back to original location
- call strcpy
- pop si ; restore regs
- pop di
- gofil5a:call strcat ; append it
- call strlen ; see if we chopped out something
- pop si ; get original length (from push cx above)
- cmp cx,si ; same size?
- je gofil9 ; e = yes
- mov flags.nmoflg,0ffh ; say that we have a replacement name
- ; filename is now in 'data', all converted
- gofil9: test flags.remflg,dquiet ; quiet display mode?
- jnz gofi10 ; nz = yes, don't print it
- cmp flags.nmoflg,0 ; using local override name?
- je gofi10 ; e = no
- mov ah,prstr
- ; mov dx,offset asmsg ; print " as "
- mcmsg asmsg,casmsg
-
- int dos
- mov dx,offset data ; plus the local filename
- call prtasz ; print asciiz string
- gofi10: mov ax,offset data ; point to name
- cmp flags.flwflg,0 ; Is file warning on?
- jne gofi100
- jmp gofi16 ; e = no, just proceed
- gofi100:call isfile ; does it exist?
- mov ax,offset data ; reload ptr in case
- jc gofi16 ; carry set = no, just proceed
- mov ah,open2 ; could it be a device name?
- mov al,0 ; open readonly
- cmp dosnum,2 ; above DOS 2?
- jna gofi10a ; na = no, so no shared access
- mov al,0+40h ; open for reading, deny none
- gofi10a:mov dx,offset data ; the filename
- int dos
- jc gofi11 ; c = cannot open so just proceed
- mov bx,ax ; file handle
- mov ah,ioctl
- mov al,0 ; get info
- int dos
- mov ah,close2 ; close it
- int dos
- mov ax,offset data ; point to filename again
- test dl,80h ; ISDEV bit set?
- jz gofi11 ; z = no, not a device
- jmp gofi16 ; device, use name as given
- gofi11: call unique ; generate unique name
- jc gofi14 ; could not generate a unique name
- test flags.remflg,dquiet ; quiet display mode?
- jnz gofi13 ; nz = yes, skip printing
- push ax ; save unique name again
- call frpos ; Position cursor.
- mov ah,prstr ; Inform the user we are renaming the file
- mcmsg infms5,cinfms5
- int dos
- pop ax ; get name back into ax again
- push ax ; save around these calls
- mov dx,ax ; print current filename
- call prtasz ; display filename
- pop ax ; pointer to name, again
- gofi13: jmp gofi16 ; and go handle file
-
- gofi14: mcmsg ermes4, cermes4
- test flags.remflg,dquiet ; quiet display mode?
- jnz gofi15 ; nz = yes, no printing
- call erpos ; Position cursor
- mov ah,prstr ; Tell the user we can't rename it
- int dos
- gofi15: mov bx,dx ; Tell host can't rename
- call errpack ; Send error packet before abort
- ret
-
- gofi16: mov si,ax ; pointer to (maybe new) name
- mov di,offset diskio.string ; filename, used in open
- mov dx,di ; for isfile and open below
- call strcpy ; copy name to diskio.string
- mov ax,0
- mov ofilsz,ax ; original file size is unknown
- mov ofilsz+2,ax ; double word
- mov tfilsz,ax ; Set bytes received to zero
- mov tfilsz+2,ax
- mov ax,-1 ; get a minus one
- mov oldkbt,ax
- mov oldper,ax
- mov diskio.handle,ax ; clear handle of previous usage
- mov ax,dx ; filename for isfile
- call isfile ; check for read-only/system/vol-label/dir
- jc gofi16a ; c = file does not exist
- test byte ptr filtst.dta+21,1fh ; the no-no file attributes
- jz gofi16b ; z = ok
- jmp gofi18 ; nz = shouldn't write over one of these
- gofi16a:test filtst.fstat,80h ; access problem?
- jnz gofi18 ; nz = yes, quit here
- mov diskio.handle,-1 ; clear handle of previous usage
- mov ah,creat2 ; DOS 2.0 create file
- mov cx,0 ; attributes bits
- int dos
- jc gofi16b ; c = did not work, try regular open
- mov diskio.handle,ax ; save file handle here
- call begtim ; start file loggging
- jmp rskp
- gofi16b:test byte ptr filtst.dta+21,1bh ; r/o, hidden, volume label?
- jnz gofi18 ; we won't touch these
- mov ah,open2 ; open existing file (usually a device)
- mov al,1+1 ; open for writing
- int dos
- jc gofi18 ; carry set means can't open
- mov diskio.handle,ax ; file handle
- call begtim ; start file loggging
- jmp rskp
-
- gofi18a:mov si,ax ; pointer to local override name
- mov di,offset diskio.string ; filename, used in open
- call strcpy ; copy name to diskio.string
- ; fall through to gofi18
- gofi18: test flags.remflg,dquiet ; quiet display mode?
- jnz gofi19 ; nz = yes, don't try printing
- call erpos ; Position cursor
- mov ah,prstr ; tell the user
- mcmsg erms12,cerms12
- int dos
- mov dx,offset diskio.string ; print offending name
- call prtasz ; display filename
- gofi19:
- ;mov dx,offset erms12 ; reset error message for packet
- mcmsg erms12,cerms12
- mov bx,dx
- call errpack ; Send an error packet
- ret
- gofi20: cmp pack.datlen,0 ; Any data in "X" packet?
- je gofi21 ; Nothing to print.
- mov ah,prstr
- mov dx,offset crlf
- int dos
- int dos ; Print another crlf
- mov di,offset data ; Where data is
- mov cx,pack.datlen ; How much data we have
- call prtscr ; Print it on the screen
- mov ah,prstr
- mov dx,offset crlf
- int dos
- gofi21: jmp rskp ; And done
-
- FILEIO ENDP
-
- ; Given incoming filename in 'data'. Verify that each char is legal
- ; (if not change it to an "X"), force max of three chars after a period (dot)
- ; Source is at ds:si (si is changed here). [jrd]
-
- VERFIL PROC NEAR
- push es ; verify each char in 'data'
- push cx
- mov ax,ds
- mov es,ax
- mov havdot,0 ; say no dot found in name yet
- cld
- verfi1: lodsb ; get a byte of name from si
- and al,7fH ; strip any eight bit
- cmp al,0 ; end of name?
- je verfi5 ; e = yes
- cmp al,'.' ; a dot?
- jne verfi2 ; ne = no
- cmp havdot,0 ; have one dot already?
- jne verfi3 ; ne = yes, change to X
- mov byte ptr [si+3],0 ; forceably end filename after 3 char ext
- mov havdot,1 ; say have a dot now
- jmp verfi4 ; continue
- verfi2: cmp al,3ah ; colon?
- je verfi4
- cmp al,5ch ; backslash path separator?
- je verfi4
- cmp al,2fh ; or forward slash?
- je verfi4
- cmp al,'0'
- jb verfi3 ; See if it's a legal char < '0'
- cmp al,'9'
- jbe verfi4 ; It's between 0-9 so it's OK
- cmp al,'A'
- jb verfi3 ; Check for a legal punctuation char
- cmp al,'Z'
- jbe verfi4 ; It's A-Z so it's OK
- cmp al,'a'
- jb verfi3 ; Check for a legal punctuation char
- cmp al,'z'
- ja verfi3
- and al,5FH ; It's a-z, capitalize
- jmp verfi4 ; continue with no change
-
- verfi3: push di ; special char. Is it on the list?
- mov di,offset spchar2 ; list of acceptable special chars
- mov cx,spc2len
- cld
- repne scasb ; Search string for input char
- pop di
- je verfi4 ; e = in table, return it
- mov al,'X' ; else illegal, replace with "X"
- mov flags.nmoflg,0FFH ; say we have a replacement filename
- verfi4: mov [si-1],al ; update name
- jmp verfi1 ; loop thru rest of name
- verfi5: mov byte ptr[si-1],0 ; make sure it's null terminated
- pop cx
- pop es
- ret
- VERFIL ENDP
-
- ; find a unique filename... Upgraded by [jrd]
- ; Enter with a pointer to a (null-terminated) filename in ax
- ; Return with same pointer but with a new name (or old if failure)
- ; Success = carry clear; failure = carry set
- ; The idea is to pad out the main name part (8 chars) with ascii zeros and
- ; then change the last chars successively to a 1, 2, etc. until
- ; a unique name is found. All registers are preserved
- ; Add patch to make empty main name fields start with letter X, not digit 0
- ; 23 March 1986 [jrd]
- unique proc near
- push bx
- push cx
- push dx
- push si
- push di
- push es
- push ax ; save address of source string
- mov dx,ds ; make es use ds segment
- mov es,dx
- mov dx,ax ; point at original filename string
- mov di,offset templp ; place for path
- mov si,offset templf ; place for filename
- call fparse ; separate path (di) and filename (si)
- mov dx,di ; point at path part
- call strlen ; put length in cx
- mov si,ax ; point to original string
- add si,cx ; point to filename part
- mov di,offset templf ; destination is temporary location
- mov cx,0 ; a counter
- cld ; set direction to be forward
- uniq1: lodsb ; get a byte
- cmp al,'.' ; have a dot?
- je uniq2 ; e = yes
- cmp al,0 ; maybe null at end?
- jne uniq3 ; ne = no. continue loop
-
- uniq2: cmp cl,8 ; have we copied any chars before dot?
- jge uniq3 ; ge = all 8
- mov byte ptr [di],'0' ; avoid clobbers; pad with 0's
- cmp cl,0 ; first char of filename?
- jne uniq2a ; ne = no
- mov byte ptr [di],'X' ; start name with letter X, not 0
- uniq2a: inc di ; and count the output chars
- inc cl ; and this counter too
- jmp uniq2 ; continue until filled 8 slots
- uniq3: inc cl ; cl = # char in destination
- stosb ; store the char
- cmp al,0 ; null at end?
- jne uniq1 ; ne = no, continue copying
-
- mov di,offset templf
- add di,7 ; address of last name char
- mov byte ptr [di],'1' ; put '1' in last name char
- mov unum,1 ; start with this generation digit
-
- uniq4: mov di,offset rdbuf ; build a temporary full filename
- mov si,offset templp ; path part
- call strcpy ; copy that much
- mov si,offset templf ; get rebuilt filename part
- call strcat ; paste that to the end
- mov ax,offset rdbuf ; point to full name
- call isfile ; does it exist?
- jc uniq6 ; c = no, succeed now
-
- inc unum ; move to next generation
- mov di,offset templf ; position for characters
- add di,7 ; point to last name char
- mov cx,7 ; max # of digits to play with
- mov bx,10 ; divisor (16 bits)
- mov ax,unum ; low order part of generation #
- uniq5: mov dx,0 ; high order part of generation #
- div bx ; compute digit (unum / 10)
- add dl,'0' ; make remainder part printable
- mov byte ptr [di],dl ; put into right place
- cmp ax,0 ; any more to do? (quotient nonzero)
- jz uniq4 ; z = no, try this name
- dec di ; else decrement char position
- loop uniq5 ; and keep making a number
- stc ; failure: set carry, keep old name
- jmp short uniq7 ; and exit
-
- uniq6: pop di ; address of original filename
- push ax ; save for exit clean up
- mov si,offset rdbuf
- call strcpy ; copy new filename over old
- clc ; success: clear carry flag
- uniq7: pop ax
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- ret
- unique endp
-
-
- ; [jrd]
- ; strlen -- computes the length, excluding the terminator, of an asciiz
- ; string. Input: dx = offset of the string
- ; Output: cx = the byte count
- ; Normal 'ret' return. All registers except cx are preserved
- ;
- STRLEN PROC NEAR
- push di
- push es
- push ax
- mov ax,ds ; use proper segment address
- mov es,ax
- mov di,dx
- mov cx,0ffffh ; large byte count
- cld ; set direction to be forward
- mov al,0 ; item sought is a null
- repne scasb ; search for it
- add cx,2 ; add for -1 and auto dec in scasb
- neg cx ; convert to count, excluding terminator
- pop ax
- pop es
- pop di
- ret
- STRLEN ENDP
-
- ; [jrd]
- ; strcat -- concatenates asciiz string 2 to the end of asciiz string 1
- ; offset of string 1 is expected to be in ds:di. input & output
- ; offset of string 2 is expected to be in ds:si. input only (unchanged)
- ; Preserves all registers. No error returns, returns normally via ret
- ;
- STRCAT PROC NEAR
- push di ; save work registers
- push si
- push es
- push dx
- push cx
- push ax
- mov ax,ds ; get data segment value
- mov es,ax ; set es to ds for implied es:di usage
- mov dx,di
- call strlen ; get length (w/o terminator) of dest string
- add di,cx ; address of first terminator
- mov dx,si ; start offset of source string
- call strlen ; find its length too (in cx)
- inc cx ; include its terminator in the count
- rep movsb ; copy source string to end of output string
- pop ax
- pop cx
- pop dx
- pop es
- pop si
- pop di
- ret
- STRCAT ENDP
-
- ; [jrd]
- ; strcpy -- copies asciiz string pointed to by ds:si into area pointed to by
- ; ds:di. Returns via ret. All registers are preserved
- ;
- STRCPY PROC NEAR
- mov byte ptr [di],0 ; clear destination string
- call strcat ; let strcat do the real work
- ret
- STRCPY ENDP
-
- ; [jrd]
- ; fparse -- separate the drive:path part from the filename.ext part of an
- ; asciiz string. Characters separating parts are \ or / or :
- ; Inputs: asciiz input full filename string offset in ds:dx
- ; asciiz path offset in ds:di
- ; asciiz filename offset in ds:si
- ; Outputs: the above strings in the indicated spots
- ; Strategy is simple. Reverse scan input string until one of the
- ; three separators is encountered and then cleave at that point
- ; Simple filename construction restrictions added 30 Dec 1985;
- ; to wit: mainname limited to 8 chars or less,
- ; extension field limited to 3 chars or less and is found by searching
- ; for first occurence of a dot in the filename field. Thus the whole
- ; filename part is restricted to 12 (8+dot+3) chars plus a null
- ; All registers are preserved. Return is always via ret
- ; (Microsoft should have written this for DOS 2.x et seq.)
-
- FPARSE PROC NEAR
- push cx ; local counter
- push ax ; local work area
- push es ; implied segment register for di
- push di ; offset of path part of output
- push si ; offset of file name part of output
- mov ax,ds ; get data segment value
- mov es,ax ; set es to ds for implied es:di usage
- mov byte ptr [si],0 ; clear outputs
- mov byte ptr [di],0
-
- push si ; save original file name address
- mov si,dx ; get original string address
- call strcpy ; copy string to original di
- call strlen ; find length (w/o terminator), in cx
- mov si,di ; address of string start
- add si,cx
- dec si ; si = address of last non-null char
- jcxz fpars5 ; if null skip the path scan
- ; now find last path char, if any
- ; start at the end of input string
- std ; set direction to be backward
- fpars4: lodsb ; get a byte (dec's si afterward)
- cmp al,5ch ; is it a backslash ('\')?
- je fpars6 ; e = yes
- cmp al,2fh ; or forward slash ('/')?
- je fpars6 ; e = yes
- cmp al,3ah ; or even the drive terminator colon?
- je fpars6 ; e = yes
- loop fpars4 ; else keep looking until cx == 0
- ; si is at beginning of file name
- fpars5: dec si ; dec for inc below
- fpars6: inc si
- inc si ; si now points at first filename char
- ; cx holds number of path chars
- ; get original file name address (si)
- pop di ; and make it place to copy filename
- cld ; reset direction to be forward
- mov ax,si ; ax holds filename address for awhile
- push dx
- mov dx,si ; strlen wants string pointer in dx
- call strlen ; get length of filename part into cx
- pop dx
- jcxz fpar7a ; any chars to look at? z = no
- fpars7: cmp byte ptr [si],'.' ; look for a dot in filename
- je fpars8 ; e = found one
- inc si ; look at next filename char
- loop fpars7 ; keep looking until cx = zero
- fpar7a: mov si,ax ; no dot. recover starting address
- mov byte ptr [si+8],0 ; forcably truncate mainname to 8 char
- call strcpy ; copy this part to filename field
- jmp fparsx ; and exit
- fpars8: mov byte ptr [si+4],0 ; plant terminator after dot + 3 ext chars
- mov cx,si
- sub cx,ax ; cx now = number of chars in mainname field
- cmp cx,9 ; more than 8?
- jb fpars9 ; b = no, we're safe
- mov cx,8 ; limit ourselves to 8 chars in mainname
- fpars9: push si ; remember address of dot and extension
- mov si,ax ; point to start of input filename
- rep movsb ; copy cx chars from si to di (output)
- mov byte ptr [di],0 ; plant terminator where dot goes
- pop si ; source = dot and extension address
- call strcat ; append the dot & ext to the filename field
- fparsx: mov si,ax ; recover start of filename in input string
- mov byte ptr [si],0 ; terminate path field
- pop si
- pop di
- pop es
- pop ax
- pop cx
- ret
- FPARSE ENDP
-
- ; Print filename in offset data. Shortened by [jrd]
- PRTFN PROC NEAR
- push ax ; saves for messy clrfln routine
- push bx
- push cx
- push dx
- push di
- call clrfln ; Position cursor & blank out the line
- mov dx,offset diskio.string
- call strlen ; compute length of asciiz string in cx
- mov di,dx ; where prtscr wants its string
- call prtscr
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- PRTFN ENDP
-
-
- ; Print string to screen from offset ds:di for # bytes given in cx,
- ; regardless of $'s. All registers are preserved. [jrd]
-
- PRTSCR PROC NEAR
- jcxz prtscr4 ; cx = zero means nothing to show
- push ax
- push bx
- push dx
- mov dx,di ; source ptr for DOS
- cmp flags.eofcz,0 ; end on Control-Z?
- jne prtscr3 ; ne = yes, let DOS do it
- push cx ; else map Control-Z to space
- push di
- push es
- push ds
- pop es ; datas to es
- mov al,ctlz ; look for Control-Z
- cld ; scan buffer es:di, cx chars worth
- prtscr1:repne scasb
- jne prtscr2 ; ne = found no Control-Z's
- mov byte ptr [di-1],' ' ; replace Control-Z with space
- jcxz prtscr2 ; z = examined all chars
- jmp short prtscr1 ; until examined everything
- prtscr2:pop es
- pop di
- pop cx
- prtscr3:mov bx,1 ; stdout file handle
- mov ah,write2
- int dos
- pop dx
- pop bx
- pop ax
- prtscr4:ret
- PRTSCR ENDP
-
- ; Print to screen asciiz string given in ds:dx. Everything preserved. [jrd]
- PRTASZ PROC NEAR
- push cx
- push di
- call strlen ; get length of asciiz string
- mov di,dx ; where prtscr looks
- call prtscr ; print counted string
- pop di
- pop cx
- ret
- PRTASZ ENDP
-
-
- ; Jumping to this location is like retskp. It assumes the instruction
- ; after the call is a jmp addr
-
- RSKP PROC NEAR
- pop bp
- add bp,3
- push bp
- ret
- RSKP ENDP
- code ends
- end
-